From 6342287288c950da08a9a06c296810c58e84bb99 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 9 Jun 2019 14:08:18 +0000 Subject: [PATCH] popover menu: Disappear on focus out We try to keep focus inside by wrapping arrow keynav. But focus can still escape. If it does, we want to disappear, like any good menu should. --- gtk/gtkpopovermenu.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c index 8bd6af266f..3c570c1d45 100644 --- a/gtk/gtkpopovermenu.c +++ b/gtk/gtkpopovermenu.c @@ -26,6 +26,8 @@ #include "gtkmenutracker.h" #include "gtkpopoverprivate.h" #include "gtkwidgetprivate.h" +#include "gtkeventcontrollerkey.h" +#include "gtkmain.h" /** @@ -137,11 +139,26 @@ visible_submenu_changed (GObject *object, g_object_notify (G_OBJECT (popover), "visible-submenu"); } +static void +focus_out (GtkEventController *controller, + GdkCrossingMode mode, + GdkNotifyType detail, + GtkPopover *popover) +{ + gboolean contains_focus; + + g_object_get (controller, "contains-focus", &contains_focus, NULL); + + if (!contains_focus) + gtk_popover_popdown (popover); +} + static void gtk_popover_menu_init (GtkPopoverMenu *popover) { GtkWidget *stack; GtkStyleContext *style_context; + GtkEventController *controller; stack = gtk_stack_new (); gtk_stack_set_vhomogeneous (GTK_STACK (stack), FALSE); @@ -153,6 +170,10 @@ gtk_popover_menu_init (GtkPopoverMenu *popover) style_context = gtk_widget_get_style_context (GTK_WIDGET (popover)); gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_MENU); + + controller = gtk_event_controller_key_new (); + g_signal_connect (controller, "focus-out", G_CALLBACK (focus_out), popover); + gtk_widget_add_controller (GTK_WIDGET (popover), controller); } static void -- 2.30.2